package com.jintian.smart.kernel.autoconfigure.extend;


import com.jintian.smart.kernel.autoconfigure.extend.impl.CachedUidGenerator;
import com.jintian.smart.kernel.autoconfigure.extend.work.LocalWorkerIdAssigner;

public class SnowGenerator {
    private static CachedUidGenerator generator;

    protected SnowGenerator() {
    }

    public static CachedUidGenerator getInstance(SnowProperties snowProperties) throws Exception {
        if (generator == null) {
            build(snowProperties);
        }
        return generator;
    }

    public static CachedUidGenerator getInstance() throws Exception {
        if (generator == null) {
            build(null);
        }
        return generator;
    }

    private static void build(SnowProperties snowProperties) throws Exception {
        if (snowProperties == null) {
            snowProperties = new SnowProperties();
        }
        LocalWorkerIdAssigner workerIdAssigner = new LocalWorkerIdAssigner();
        generator = new CachedUidGenerator(workerIdAssigner, snowProperties);

//        // 以下为可选配置, 如未指定将采用默认值
//        if (snowProperties.getTimeBits() > 0) {
//            generator.setTimeBits(snowProperties.getTimeBits());
//        }
//        if (snowProperties.getWorkerBits() > 0) {
//            generator.setWorkerBits(snowProperties.getWorkerBits());
//        }
//        if (snowProperties.getSeqBits() > 0) {
//            generator.setSeqBits(snowProperties.getSeqBits());
//        }
//        if (StringUtil.isNotEmpty(snowProperties.getEpochStr())) {
//            generator.setEpochStr(snowProperties.getEpochStr());
//        }
//
//        // RingBuffer size扩容参数, 可提高UID生成的吞吐量
//        // 默认:3， 原bufferSize=8192, 扩容后bufferSize= 8192 << 3 = 65536
//        if (snowProperties.getBoostPower() > 0) {
//            generator.setBoostPower(snowProperties.getBoostPower());
//        }
//
//        // 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50
//        // 举例: bufferSize=1024, paddingFactor=50 -> threshold=1024 * 50 / 100 = 512.
//        // 当环上可用UID数量 < 512时, 将自动对RingBuffer进行填充补全
//        if (snowProperties.getPaddingFactor() > 0) {
//            generator.setPaddingFactor(snowProperties.getPaddingFactor());
//        }
//
//        // 另外一种RingBuffer填充时机, 在Schedule线程中, 周期性检查填充
//        // 默认:不配置此项, 即不使用Schedule线程. 如需使用, 请指定Schedule线程时间间隔, 单位:秒
//        if (snowProperties.getScheduleInterval() > 0) {
//            generator.setScheduleInterval(snowProperties.getScheduleInterval());
//        }

        // 拒绝策略: 当环已满, 无法继续填充时
        // 默认无需指定, 将丢弃Put操作, 仅日志记录. 如有特殊需求, 请实现RejectedPutBufferHandler接口(支持Lambda表达式)
        // <property name="rejectedPutBufferHandler"
        // ref="XxxxYourPutRejectPolicy"></property>
        // cachedUidGenerator.setRejectedPutBufferHandler();
        // 拒绝策略: 当环已空, 无法继续获取时 -->
        // 默认无需指定, 将记录日志, 并抛出UidGenerateException异常. 如有特殊需求,
        // 请实现RejectedTakeBufferHandler接口(支持Lambda表达式) -->
        // <property name="rejectedTakeBufferHandler"
        // ref="XxxxYourTakeRejectPolicy"></property>
//        return generator;
    }
}
